/**
 *Copyright (c) 2024 watereyes
 * workflow is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.workflow.workflowMonitoring.service.impl;

import com.koron.workflow.common.bean.PageBean;
import com.koron.workflow.common.bean.StaffBean;
import com.koron.workflow.common.util.BusinessCode;
import com.koron.workflow.workflowDesign.mapper.ProcessSetMapper;
import com.koron.workflow.workflowMonitoring.bean.MonitoringQueryForListBean;
import com.koron.workflow.workflowMonitoring.bean.QueryHistorytaskmsgBeam;
import com.koron.workflow.workflowMonitoring.mapper.WorkflowMonitoringMapper;
import com.koron.workflow.workflowMonitoring.service.WorkflowMonitoringService;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WorkflowMonitoringServiceImpl implements WorkflowMonitoringService {
    private static final Logger logger = LoggerFactory.getLogger(WorkflowMonitoringServiceImpl.class);

    @TaskAnnotation("queryMonitoringProcessList")
    @Override
    public List<Map> queryMonitoringProcessList(SessionFactory factory, StaffBean user) {
        ProcessSetMapper processSetMapper = factory.getMapper(ProcessSetMapper.class);
        // 根据用户帐号 查询系统管理员ID
        String administratorId = processSetMapper.queryAdminIdByUsercode(user.getAccount());
        WorkflowMonitoringMapper monitoringMapper = factory.getMapper(WorkflowMonitoringMapper.class);
        // 根据系统管理员ID 查询用户有监控权限的模版组
        List<Map> list = monitoringMapper.queryMonitoringProcessList(administratorId);
        if (list == null || list.size() < 1) {
            return list;
        }
        List<Map> appProcessList = new LinkedList();
        list.stream().forEach(map -> {
            if (!appProcessList.stream().map(appProcess -> appProcess.get("appId").toString()).collect(Collectors.toList())
                    .contains(map.get("appId").toString())) {
                Map appProcessMap = new HashMap();
                String appId = map.get("appId").toString();
                appProcessMap.put("appId", appId);
                appProcessMap.put("appName", map.get("appName").toString());
                appProcessMap.put("appCode", map.get("appCode").toString());
                appProcessMap.put("label", map.get("appName").toString());
                List setList = new LinkedList();
                list.stream().forEach(map1 -> {
                    if (map1.get("setAppId") != null && appId.equals(map1.get("setAppId").toString())) {
                        map1.put("label", map1.get("setName").toString());
                        setList.add(map1);
                    }
                });
                appProcessMap.put("sets", setList);
                appProcessList.add(appProcessMap);
            }
        });
        return appProcessList;
    }

    @TaskAnnotation("queryForList")
    @Override
    public PageBean queryForList(SessionFactory factory, StaffBean user, String appId,
                                 String setId, String code, String name,
                                 String title, Integer page, Integer pageSize) {
        ProcessSetMapper processSetMapper = factory.getMapper(ProcessSetMapper.class);
        // 根据用户帐号 查询系统管理员ID
        String administratorId = processSetMapper.queryAdminIdByUsercode(user.getAccount());
        WorkflowMonitoringMapper mapper = factory.getMapper(WorkflowMonitoringMapper.class);
        List<MonitoringQueryForListBean> list = mapper.queryForList(administratorId, appId, setId, code, name, title, page, pageSize);
        if (list != null && list.size() > 0) {
            for (MonitoringQueryForListBean bean : list) {
                // 实例状态 1正常运行中 2.正常结束和直接终止 4.异常结束
                if (bean.getStatus() == 1) {
                    bean.setStatusName("正常运行中");
                } else if (bean.getStatus() == 2) {
                    bean.setStatusName("正常结束和直接终止");
                } else if (bean.getStatus() == 4) {
                    bean.setStatusName("异常结束");
                } else {
                    bean.setStatusName("");
                }
            }
        }
        Integer total = null;
        if (page != null || pageSize != null) {
            total = mapper.countQueryForList(administratorId, appId, setId, code, name, title);
        }
        return new PageBean<>(list, total);
    }

    @TaskAnnotation("endTask")
    @Override
    public MessageBean endTask(SessionFactory factory, String tasklistId) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        try {
            WorkflowMonitoringMapper mapper = factory.getMapper(WorkflowMonitoringMapper.class);
            // 根据任务列表ID 修改实例状态为 2   (1正常运行中 2.正常结束和直接终止 4.异常结束)
            if (mapper.updateStatusByTasklistId(tasklistId, 2) != 1) {
                factory.close(false);
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription(BusinessCode.FAILURE.getDescription());
                return msg;
            }
        } catch (Exception e) {
            factory.close(false);
            logger.error("工作流监控结束失败", e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @TaskAnnotation("delete")
    @Override
    public MessageBean delete(SessionFactory factory, String processInstanceId) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        try {
            WorkflowMonitoringMapper mapper = factory.getMapper(WorkflowMonitoringMapper.class);
            // 根据流程实例Id删除 工作流历史任务信息 tblhistorytaskmsg
            mapper.deleteHistorytaskmsgByProcessInstanceId(processInstanceId);
            // 根据流程实例Id删除 用户任务关系表 tblrelation
            mapper.deleteRelationByProcessInstanceId(processInstanceId);
            // 根据流程实例Id删除 任务列表 tbltasklist
            mapper.deleteTasklistByProcessInstanceId(processInstanceId);
            // 根据流程实例Id删除 业务单据列表 tblhistorybills
            if (mapper.deleteHistorybillsByProcessInstanceId(processInstanceId) != 1) {
                factory.close(false);
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription(BusinessCode.FAILURE.getDescription());
                return msg;
            }
        } catch (Exception e) {
            factory.close(false);
            logger.error("工作流监控删除失败", e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @TaskAnnotation("queryHisNodeMsgs")
    @Override
    public List queryHisNodeMsgs(SessionFactory factory, String curTaskId, String processInstanceId) {
        WorkflowMonitoringMapper mapper = factory.getMapper(WorkflowMonitoringMapper.class);
        // 根据 流程实例Id 工作流历史任务信息
        List<QueryHistorytaskmsgBeam> list = mapper.queryHistorytaskmsg(processInstanceId);
        if (list != null && list.size() > 0) {
            // 当前节点
            String nowTaskId = curTaskId;
            // 筛选出当前节点及之前节点信息
            List<QueryHistorytaskmsgBeam> nodes = new LinkedList<>();
            for (QueryHistorytaskmsgBeam beam : list) {
                if (nowTaskId.equals(beam.getNowTaskId())) {
                    nodes.add(beam);
                    filterMap(nowTaskId, list, nodes);
                }
            }
            return nodes;
        }
        return null;
    }

    @TaskAnnotation("getRejectParams")
    @Override
    public Map getRejectParams(SessionFactory factory, String processInstanceId) {
        WorkflowMonitoringMapper mapper = factory.getMapper(WorkflowMonitoringMapper.class);
        // 根据流程实列ID 获取要进行驳回参数信息
        return mapper.getRejectParams(processInstanceId);
    }

    /**
     * 递归函数
     *
     * @param nowTaskId
     * @param list
     * @param nodes
     */
    private void filterMap(String nowTaskId, List<QueryHistorytaskmsgBeam> list, List<QueryHistorytaskmsgBeam> nodes) {
        for (QueryHistorytaskmsgBeam beam : list) {
            if (nowTaskId.equals(beam.getNextTaskId())) {
                nodes.add(beam);
                filterMap(beam.getNowTaskId(), list, nodes);
            }
        }
    }
}
